package com.trip.config;

import com.trip.api.AuthInterceptor;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.ssl.TrustStrategy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import javax.net.ssl.SSLContext;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

/**
 * @author hc24
 * @version 2017/9/27
 */
@Configuration
@EnableConfigurationProperties(CommonProperties.class)
public class CommonAutoConfiguration {

    @Autowired
    private CommonProperties commonProperties;

    @Autowired
    private RestTemplateBuilder builder;

    @Bean
    public RestTemplate restTemplate() {
        SSLContext sslcontext;

        // Trust all certs
        try {
            sslcontext = SSLContexts.custom().loadTrustMaterial(null, new TrustAllStrategy(true)).build();
        } catch (Exception e) {
            throw new RuntimeException("Failed to init SSLContext for RestTemplate", e);
        }

        // Allow all hostnames
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1.2" }, null,
                new NoopHostnameVerifier());

        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(120000)
                .setConnectionRequestTimeout(120000).setSocketTimeout(180000).build();

        HttpClientBuilder httpClientBuilder = HttpClients.custom().setSSLSocketFactory(sslsf)
                .setDefaultRequestConfig(requestConfig);

        CloseableHttpClient httpClient = httpClientBuilder.build();

        ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
        return new RestTemplate(requestFactory);
    }

    private static final class TrustAllStrategy implements TrustStrategy {
        private boolean trustAll;

        public TrustAllStrategy(boolean trustAll) {
            this.trustAll = trustAll;
        }

        @Override
        public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            return trustAll;
        }
    }

    @Bean
    public MethodValidationPostProcessor methodValidationPostProcessor() {
        return new MethodValidationPostProcessor();
    }

//    @Bean(value = "druid-stat-interceptor")
//    public DruidStatInterceptor druidStatInterceptor(){
//        DruidStatInterceptor interceptor=new DruidStatInterceptor();
//        return interceptor;
//    }

//    @Bean
//    public RegexpMethodPointcutAdvisor druidPointcutAdvisor(){
////        JdkRegexpMethodPointcut pointcut=new JdkRegexpMethodPointcut();
////        pointcut.setPattern("com.trip.service.*");
//       RegexpMethodPointcutAdvisor advisor=new RegexpMethodPointcutAdvisor();
//        advisor.setAdvice(new DruidStatInterceptor());
//        advisor.setPattern("com.trip.service.*");
//
//        return advisor;
//    }
//
//    @Bean
//    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){
//        DefaultAdvisorAutoProxyCreator creator= new DefaultAdvisorAutoProxyCreator();
//        creator.setProxyTargetClass(true);
//        return creator;
//    }

    @Configuration
    public class MyWebMvcConfigurer extends WebMvcConfigurerAdapter {
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new AuthInterceptor()).addPathPatterns("/**");
            super.addInterceptors(registry);
        }
    }


}
